package com.bjpowernode.boss.mvc.service.Impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.crypto.digest.DigestUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.bjpowernode.boss.common.client.RedisClient;
import com.bjpowernode.boss.common.consants.KeyConsant;
import com.bjpowernode.boss.common.enums.ResponseCode;
import com.bjpowernode.boss.common.expection.BossExpection;
import com.bjpowernode.boss.common.utils.Jwtutil;
import com.bjpowernode.boss.dao.entity.PmsMenu;
import com.bjpowernode.boss.dao.entity.PmsOperator;
import com.bjpowernode.boss.dao.mapper.PmsMenuMapper;
import com.bjpowernode.boss.dao.mapper.PmsOperatorMapper;
import com.bjpowernode.boss.mvc.menus.MenuItem;
import com.bjpowernode.boss.mvc.menus.SubMenu;
import com.bjpowernode.boss.mvc.models.dto.operator.LoginResponseDto;
import com.bjpowernode.boss.mvc.models.form.operator.LoginForm;
import com.bjpowernode.boss.mvc.service.OperatorService;
import jakarta.annotation.Resource;
import org.apache.logging.log4j.util.PropertySource;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.concurrent.TimeUnit;

@Service
public class OperatorServiceImpl implements OperatorService {

    @Resource
    private RedisClient redisClient;
    @Resource
    private PmsOperatorMapper operatorMapper;

    @Resource
    private PmsMenuMapper menuMapper;

    @Override
    public LoginResponseDto operatorLogin(LoginForm loginForm) {
        QueryWrapper<PmsOperator> wrapper = new QueryWrapper<>();
        wrapper.eq("login_name", loginForm.getLoginName());
        PmsOperator pmsOperator = operatorMapper.selectOne(wrapper);

        if (pmsOperator == null) {
            throw new BossExpection(ResponseCode.OPEOATOR_LOGIN_NAME_PWD);
        }

        String salt = pmsOperator.getSalt();

        String requestLoginPwd = DigestUtil.md5Hex(loginForm.getLoginPwd() + salt);
        if (!requestLoginPwd.equals(pmsOperator.getLoginPwd())) {
            throw new BossExpection(ResponseCode.OPEOATOR_LOGIN_NAME_PWD_1);
        }
        String jwt = Jwtutil.createJWT(UUID.randomUUID().toString(), 120);
        Map<String, String> redisData = new HashMap<>();
        redisData.put("jwt", jwt);
        redisData.put("operatorId", String.valueOf(pmsOperator.getId()));
        redisData.put("loginTime", DateUtil.format(new Date(), "yyyy-MM-dd HH:mm:ss"));
        String loginKey = KeyConsant.TOKEN_OPERATOR + pmsOperator.getId();

        Boolean saveToken = redisClient.setHashMap(loginKey, redisData, 120, TimeUnit.MINUTES);

        if (!saveToken) {
            throw new BossExpection(ResponseCode.OPEOATOR_SAVE_TOKEN);
        }

        //登录成功， jwt成功。返回登录结果给前端
        return new LoginResponseDto(pmsOperator.getId(), pmsOperator.getShowName(), jwt);

    }

    @Override
    public List<SubMenu> getMenusByLoginUser(Long operatorId) {
        //从数据库查询菜单数据
        List<PmsMenu> pmsMenuList = menuMapper.selectListByUserId(operatorId);

        //Map<String,List<PmsMenu>   key是number列的前4位， value：number前4位相同的List
        String numberPrefix4 = "";
        Map<String,List<PmsMenu>> listMapMenu=  new HashMap<>();
        for (PmsMenu pmsMenu : pmsMenuList) {
            numberPrefix4 = pmsMenu.getNumber().substring(0,4);

            if( listMapMenu.containsKey(numberPrefix4 )){
                // 有numberPrefix4的key， 获取value。添加PmsMenu到List集合
                listMapMenu.get(numberPrefix4).add(pmsMenu);
            } else {
                // 没有 numberPrefix4的key
                List<PmsMenu> itemsList = new ArrayList<>();
                itemsList.add(pmsMenu);
                listMapMenu.put(numberPrefix4,itemsList);
            }

        }

        //从Map中查询菜单， 对List计划进行组装， 得到List<SubMenu>
        List<SubMenu> subMenuList  = new ArrayList<>();
        listMapMenu.forEach(  ( number , menusList ) ->{
            String leaf = "";
            SubMenu subMenu  = new SubMenu();
            List<MenuItem> items = new ArrayList<>();


            for (PmsMenu pmsMenu : menusList) {
                leaf = pmsMenu.getIsLeaf();
                if("NO".equals(leaf)){
                    subMenu.setName(pmsMenu.getName());
                    subMenu.setUrl(pmsMenu.getUrl());
                    subMenu.setNumber(pmsMenu.getNumber());
                } else {
                    MenuItem item = new MenuItem();
                    item.setName(pmsMenu.getName());
                    item.setUrl(pmsMenu.getUrl());
                    item.setNumber(pmsMenu.getNumber());
                    items.add(item);
                }
            }

            //SubMenu的items赋值
            subMenu.setItems(items);
            subMenuList.add(subMenu);
        });

        return subMenuList.stream().sorted(Comparator.comparing(SubMenu::getNumber)).toList();
    }
}
